home *** CD-ROM | disk | FTP | other *** search
-
- /*****************************************************************
- *
- * f8.ca: additional subroutines for ST text screen dump:
- * part 3 of 3.
- * Megamax in-line version.
- *
- *
- ******************************************************************/
-
-
-
- /****
- *
- * dump_line-- dump a line's worth of screen text data.
- *
- * at entry:
- * (a6) + 8 -> point to begin from (byte address).
- * (a6) + 12 -> font header.
- * [(a6) + 16 -> ascii code returned by 'recognize'.]
- * (a6) + 20 -> bit offset of start point.
- * (a6) + 24 -> length of screen line in bytes.
- * (a6) + 28 -> space to save dumped codes.
- *
- * internal usage:
- * d0 -- miscellaneous & function return.
- * d1 -- ascii code from 'recognize()'.
- * d2 -- unused.
- * d3 -- bit offset.
- * d4 -- character cell width.
- * d5 -- loop iteration counter.
- * d6 -- unused.
- * d7 -- hash index.
- *
- * a0 -- pointer to collision list.
- * a1 -- char byte address.
- * a2 -- hash table base.
- * a3 -- memory end address.
- * a4 -- pointer to dump string space, or
- * -- link register to Megamax C global variables.
- * a5 -- font header pointer (not used during loop).
- * a6 -- frame pointer.
- *
- * at exit:
- * d0 == 0 if no error, -1 if error detected (i.e., first
- * character in line was not the same as that returned
- * by 'recognize').
- * all other registers preserved.
- *
- *
- ****/
- dump_line:
- link A6,#-MAX_SCAN ;frame pointer
- movem.l A0-A5/D1-D7,-(A7) ;save registers
-
- move.l #1,D6 ;init invert flag
- movea.l 12(A6),A5 ;font header pointer
- movea.l 8(A6),A1 ;start point
- move.l 16(A6),D1 ;first ascii code-- we hope
- move.l 20(A6),D3 ;bit offset of start
- move.l A1,-(A7) ;push byte address
- bsr find_end ;find end address of line
- movea.l (A7)+,A3 ;do it
- move.l #-1,D0 ;get a4
- bsr reg_a4 ;do it
- movea.l hash_table(A4),A2 ;hash table base
-
- movea.l 28(A6),A4 ;save dump space
-
- move.l #0,D0 ;clear registers
- move.l #0,D2
- move.l #0,D4
- move.l #0,D5
- move.l #0,D7
- move.w BIG_CELL_WD(A5),D4 ;char cell width
-
- dump_l_loop:
- move.l A4,-(A7) ;save a4
- move.l #-1,D0 ;get link a4 (I hate this)
- bsr reg_a4 ;do it
- move.l D6,-(A7) ;invert flag
- move.l resolution(A4),-(A7) ;scan length
- move.l D3,-(A7) ;bit offset
- pea -MAX_SCAN(A6) ;space for scan slices
- move.l A5,-(A7) ;font header
- move.l A1,-(A7) ;byte address current char
- bsr make_slices ;get hash value in d7
- adda.l #24,A7 ;pop args
- movea.l (A7)+,A4 ;restore a4
-
- mulu #HASH_IX,D7 ;make it an index
- tst.l 2(A2,D7.l) ;test for collision
- beq d_l_no_coll ;if none
- bmi dump_l_retry ;if bad hash element
- movea.l 2(A2,D7.l),A0 ;else get pointer
-
- pea -MAX_SCAN(A6) ;push scan vals list
- move.l A0,-(A7) ;push start of collision list
- bsr find_collide ;find a match
- addq.l #8,A7 ;pop args
- tst.l D0 ;error?
- bne.s d_l_process ;if not, d0.w has code
- d_l_no_coll:
- clr.l D0 ;clear for word
- move.w 0(A2,D7.l),D0 ;default code
-
- /* process the code */
- /* first, double check: */
- d_l_process:
- cmp.b #FIRST_VALID,D0 ; < lowest valid char?
- bmi dump_l_retry ;reject invalid char
- cmp.b #LAST_ASCII,D0 ; > highest valid char?
- bgt dump_l_retry ;reject invalid char
- d_l_insert:
- move.b D0,(A4)+ ;save the code
-
- cmpi.l #1,D6 ;was this an invert?
- beq.s d_l_ninv ;if not
- add.l #-1,D6 ;else don't invert any more
-
- d_l_ninv:
- /* now increment to next char cell */
- add.l D4,D3 ;add cell width to bit offset
- d_l_continue:
- cmp.l #BYTESIZE,D3 ; < byte ?
-
- bmi d_l_002 ;if so, continue at same addr
- bne d_l_003 ;if not byte-aligned result
- clr.l D3 ;else make offset = 0
- bra d_l_004 ;and continue
- d_l_003:
- sub.l #BYTESIZE,D3 ;subtract one byte size
- d_l_004:
- addq.l #1,A1 ;increment byte address
- d_l_002:
- addq.l #1,D5 ;iteration counter
- cmpa.l A1,A3 ;at end?
- beq dump_exit ;if so
- bra dump_l_loop ;else continue
- dump_exit:
- move.l #0,D0 ;success code
-
- dump_l_exit:
- move.b #NULL,(A4) ;mark end of string
- movem.l (A7)+,A0-A5/D1-D7 ;restore registers
- unlk A6 ;deallocate frame
- rts
-
- /* next couple of lines are meaningless now */
- dump_l_retry:
- addq.l #1,D3 ;so try next bit offset
- cmp.l #RETRIES,D5 ;...for a byte or so
- bmi d_l_continue ;do it
- move.l A4,-(A7) ;save dump space pointer
- move.l #-1,D0 ;get link register
- bsr reg_a4 ;do it
- addq.l #1,hash_errors(A4) ;else inc hash error count
- movea.l (A7)+,A4 ;recover dump space pointer
-
- /* following is designed to handle character cell where cursor */
- /* happens to be. */
-
- tst.l D6 ;inverted already?
- bmi.s bad_inv ;if so, leave
- add.l #-1,D6 ;else decrement
- bra dump_l_loop ;and try again
- bad_inv:
- move.l #-1,D0 ;error code
- bra dump_l_exit ;leave
-
-
- /****
- *
- * find_end-- return end address of current screen line.
- *
- * at entry:
- * (a6) + 8 -> current byte address.
- * all other parms are values from the data or bss segments!
- *
- * at exit:
- * (a6) + 8 -> end address, current line.
- * all other registers preserved.
- *
- *
- ****/
- find_end:
- link A6,#0 ;frame pointer
- movem.l D0-D1/A4,-(A7) ;save registers
-
- move.l #-1,D0 ;get a4
- bsr reg_a4 ;do it
- move.l 8(A6),D0 ;get current address
- #ifdef SC_IMAGE
- sub.l base(A4),D0 ; - base = logical address
- move.l resolution(A4),D1 ;get resolution
- divu D1,D0 ;logical address / resolution
- mulu D1,D0 ;quotient * resolution = start
- add.l D1,D0 ; + resolution = logical end
- add.l base(A4),D0 ; + base = physical end
- #endif
- #ifdef NO_IMAGE
- add.l resolution(A4),D0 ;find end
- #endif
- move.l D0,8(A6) ;put result on stack
-
- movem.l (A7)+,D0-D1/A4 ;restore registers
- unlk A6 ;deallocate frame pointer
- rts
-
-
- /****
- *
- * set_window-- set up system variables for dump window coordinates.
- *
- * at entry:
- * (a6) + 8 -> window height.
- * (a6) + 12 -> window width.
- * (a6) + 16 -> top left y-coordinate.
- * (a6) + 20 -> top left x-coordinate.
- * (a6) + 24 -> scan line length (== resolution).
- * (a6) + 28 -> start address storage area.
- * (a6) + 32 -> font header.
- *
- * at exit:
- * system variables are set to correct values.
- * registers are preserved.
- *
- *
- ****/
- set_window:
- link A6,#0 ;frame pointer
- movem.l D0-D2/A0-A2/A4/A5,-(A7) ;save registers
-
- move.l #-1,D0 ;get a4
- bsr reg_a4 ;do it
- movea.l 32(A6),A5 ;font header
-
- move.w #3,-(A7) ;code = get logbase
- trap #14 ;do it
- addq.l #2,A7 ;pop arg
-
- move.l D0,-(A7) ;save orig screen base
- move.l 16(A6),D1 ;get y coordinate
-
- move.l y_align(A4),D0 ;get alignment factor
- divu D0,D1 ;divide y-coord by it
- mulu D0,D1 ;mult result by factor
-
- move.l 24(A6),D0 ;get scan line length
- mulu D0,D1 ; == logical pixel position
- add.l (A7)+,D1 ; == start row on screen
- andi.l #-2,D1 ;else ensure even number
- move.l D1,screen_base(A4) ;save it
-
- #ifdef SC_IMAGE
- move.l chunk(A4),base(A4) ;base of storage area
- #endif
- #ifdef NO_IMAGE
- move.l D1,base(A4) ;direct from screen
- #endif
-
- move.l 8(A6),screen_height(A4) ;nr of scan lines to save
-
- move.l 20(A6),D1 ;x coordinate
- divu #BYTESIZE,D1 ;as byte address
- swap D1 ;access remainder
- move.w D1,xshift(A4) ;save it
- swap D1 ;get quotient again
- andi.l #0xffff,D1 ;discard remainder
-
- move.l D1,front(A4) ; == front line offset
-
- move.l D1,-(A7) ;save 'front'
- move.l 12(A6),D1 ;width of line
- divu #BYTESIZE,D1 ;as byte address
- andi.l #0xffff,D1 ;discard remainder
- add.l (A7)+,D1 ; + 'front' == end
- sub.l D1,D0 ;subtract from scan length
-
- move.l D0,back(A4) ; == back line offset
-
- add.l front(A4),D0 ;add front to back offset
- move.l resolution(A4),D1 ;get old byte length
- sub.l D0,D1 ;subtract offsets
- move.l D1,resolution(A4) ; == new resolution
-
- clr.l D0 ;clear for word
- move.w FORM_HEIGHT(A5),D0 ;char scan height
- add.w form_inc(A4),D0 ; + user-requested inc
- move.l D0,form_ht(A4) ;effective scan height
- mulu D0,D1 ; * resolution = text line len
- move.l D1,line_size(A4) ;save it
-
- move.l scrn_text(A4),D1 ;full screen line byte length
- mulu D0,D1 ; * cell height
- move.l D1,scrn_size(A4) ; == screen text line
-
- move.l 8(A6),D1 ;get window height
- divu D0,D1 ;divide by cell height
- andi.l #0xffff,D1 ;discard remainder
- /* unscale */
- cmpi.l #4,res_ix(A4) ;medium res?
- bne.s sw_notmed ;if not
- lsr.l #1,D1 ;else unscale line count
- sw_notmed:
- cmpi.l #0,res_ix(A4) ;low res?
- bne.s sw_notlow ;if not
- lsr.l #2,D1 ;else unscale line count
- sw_notlow:
- move.l D1,line_count(A4) ; == number of text lines
-
- move.l 8(A6),D1 ;window height
- move.l resolution(A4),D0 ;wind line length in bytes
- mulu D0,D1 ;byte size of window
- move.l D1,-(A7) ;save it
- lsr.l #1,D1 ; / 2 == word size
- move.l D1,screen_size(A4) ;save it
- move.l (A7)+,D1 ;recover size in bytes
- #ifdef NO_IMAGE
- move.l #SMALL_SCRN,D1 ;
- #endif
- add.l base(A4),D1 ; == phys addr last byte
- move.l D1,last(A4) ;save it
- move.l D1,chunk_end(A4) ;twice
-
- movem.l (A7)+,D0-D2/A0-A2/A4/A5 ;restore registers
- unlk A6 ;deallocate frame
- rts ;dummy comment
-
-
-